package com.keqiang.chart.impl.axis.impl.line

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Shader
import android.graphics.drawable.Drawable
import androidx.annotation.ColorInt
import androidx.annotation.FloatRange
import androidx.annotation.IntDef
import androidx.annotation.Px
import com.keqiang.chart.base.BaseChartView
import com.keqiang.chart.impl.axis.*
import com.keqiang.chart.impl.axis.render.BaseDataRender
import com.keqiang.chart.impl.axis.render.XAxisRender
import com.keqiang.chart.impl.axis.render.YAxisRender
import com.keqiang.chart.utils.DefValueDelegate

/**
 * 折线图
 *
 * @author Created by wanggaowan on 2022/7/29 15:15
 */
open class LineChart(view: BaseChartView<*>) : BaseAxisChart<List<LineData>>(view) {
    override var xAxis: XAxis = XAxis()
    override var yAxis: YAxis = YAxis()
    override var yAxisRender: YAxisRender<LineChart> = YAxisRender(this)
    override var xAxisRender: XAxisRender<LineChart> = XAxisRender(this)
    override var dataRender: BaseDataRender<LineChart> = LineChartDataRender(this)
    override var touchHandler: BaseTouchHandler<LineChart, List<LineEntity>>? =
        LineTouchHandler(this)

    var highLightRender: HighLightRender? = null

    override fun isEmptyData(): Boolean {
        if (data.isNullOrEmpty()) {
            return true
        }

        var isEmpty = true
        for (d in data!!) {
            if (d.values.isNotEmpty()) {
                isEmpty = false
                break
            }
        }
        return isEmpty
    }
}

/**
 * 高亮数据绘制器
 *
 * @author Created by wanggaowan on 2022/11/1 10:04
 */
abstract class HighLightRender(val chart: LineChart) {
    /**
     * 绘制高亮内容，此时[AxisEntity.drawRectF]已就绪
     *
     * @param canvas 画布
     * @param start  水平可绘制区域起始点坐标 = x轴起始点 + [XAxis.startPadding]
     * @param top    可绘制区域顶部坐标 = y轴顶部 - [YAxis.endPadding]
     * @param end    水平可绘制区域结束点坐标 = x轴结束点 - [XAxis.endPadding]
     * @param bottom 可绘制区域底部坐标 = y轴底部 + [YAxis.startPadding]
     */
    abstract fun onDraw(canvas: Canvas, start: Float, top: Float, end: Float, bottom: Float, data: List<LineEntity>)
}

/**
 * 折线图数据
 */
open class LineData(
    /**
     * 需要绘制的值
     */
    var values: List<LineEntity>
) {

    /**
     * 绘制折线类型
     */
    @setparam:LineStyle
    var lineStyle: Int = LINER

    /**
     * 如果[lineStyle]是[CUBIC_BEZIER],则此值指定贝塞尔曲线的平滑度
     */
    var cubicIntensity by DefValueDelegate {
        when (lineStyle) {
            CUBIC_BEZIER -> 0.1f
            else -> 0f
        }
    }

    /**
     * 绘制折线宽度
     */
    @setparam:Px
    @setparam:FloatRange(from = 1.0)
    var lineWidth: Float = 1f

    /**
     * 绘制折线颜色
     */
    @setparam:ColorInt
    var lineColor: Int = Color.GRAY

    /**
     * 线条的着色器工厂，实现渐变色。该方法在绘制过程多次调用，因此不要每次调用都创建新对象
     */
    var lineShaderFactory: ((left: Float, top: Float, right: Float, bottom: Float) -> Shader)? =
        null

    /**
     * 是否填充背景
     */
    var fillBg: Boolean = false

    /**
     * 填充的背景颜色，如果设置了此值也设置了[fillBgDrawable],则优先使用[fillBgDrawable]。
     */
    var fillBgColor: Int = 0

    /**
     * 填充的背景图像
     */
    var fillBgDrawable: Drawable? = null

    /**
     * 附加线数据
     */
    var addedLines: List<AddedLine>? = null

    /**
     * 折线绘制时，是否可以超出轴线。超出的情况只在[lineStyle] == [CUBIC_BEZIER]和[HORIZONTAL_BEZIER]时发生
     */
    var lineDrawCouldBeyondAxis: Boolean = false

    @IntDef(LINER, CUBIC_BEZIER, HORIZONTAL_BEZIER)
    @Target(AnnotationTarget.VALUE_PARAMETER)
    @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
    private annotation class LineStyle

    companion object {
        /**
         * 直线
         */
        const val LINER = 1

        /**
         * 三次贝塞尔曲线
         */
        const val CUBIC_BEZIER = 2

        /**
         * 二次贝塞尔曲线
         */
        const val HORIZONTAL_BEZIER = 3
    }
}